package model;

import java.util.Collection;
import java.util.Iterator;
import java.util.Vector;

public class Stepper implements Runnable,Observer {
	
	private final Configuration configuration;
	private final StepperManager manager;
	private boolean stopped;

	public Stepper(final Configuration configuration, final StepperManager manager) {
		this.configuration = configuration;
		this.manager = manager;
		this.manager.register(this);
	}

	@Override
	public void run() {
		// TODO vor dem senden des result deregistrieren!
		while(!stopped){
			final Collection<Transition> suitableTransitions = manager.getAutomaton().getSuitableTransitions(
					this.configuration.getState(),this.configuration.getCurrentChar());
			if(!suitableTransitions.isEmpty()){
				final Iterator<Transition> i = suitableTransitions.iterator();
				while(i.hasNext()){
					final Transition t = i.next();
					if(!i.hasNext()){
						step(t);
					}else{
						new Thread(new Stepper(new Configuration(this.getManager().getAutomaton(), t.target,
						this.getConfiguration().getInput(), this.getConfiguration().getPosition()+1), getManager())).start();
					}
				}
			}else{
				this.stop();
			}
		}
	}

	private void step(final Transition t) {
		this.getConfiguration().setLatestOutput(new StringTreeElement(t.getOutput(), this.getConfiguration().getLatestOutput()));
		this.getConfiguration().setPosition(this.getConfiguration().getPosition()+1);
		this.getConfiguration().setState(t.target);
		
	}

	private StepperManager getManager() {
		return manager;
	}

	private Configuration getConfiguration() {
		return configuration;
	}

	@Override
	public void stop() {
		this.stopped = true;
		this.getManager().deregister(this);
	}
	
}
